package com.erlang4j.internal.messages;

import static com.erlang4j.api.Erlang4jMessageLanguage.atom;
import static com.erlang4j.api.Erlang4jMessageLanguage.binding;
import static com.erlang4j.api.Erlang4jMessageLanguage.floating;
import static com.erlang4j.api.Erlang4jMessageLanguage.integer;
import static com.erlang4j.api.Erlang4jMessageLanguage.list;
import static com.erlang4j.api.Erlang4jMessageLanguage.string;
import static com.erlang4j.api.Erlang4jMessageLanguage.tuple;
import junit.framework.TestCase;

import com.ericsson.otp.erlang.OtpErlangObject;
import com.erlang4j.api.exceptions.Erlang4jMissingParameterException;
import com.erlang4j.tests.Erlang4JTestHelper;

public class MessageComposerTest extends TestCase {
	MessageComposer messageComposer = new MessageComposer(binding("X", "x"));

	public void testComposeFromBinding() {
		checkComposeFromBinding("a", atom("a"));
		checkComposeFromBinding("{a}", tuple(atom("a")));
		checkComposeFromBinding("[a]", list(atom("a")));
		checkComposeFromBinding("{a,[b]}", tuple(atom("a"), list(atom("b"))));
		checkComposeFromBinding("{a,[X]}", tuple(atom("a"), list(string("x"))));
		checkComposeFromBinding("{a,[Var]}", tuple(atom("a"), list(string("value"))), "Var", string("value"));
	}

	public void testComposeFromParameters() {
		checkComposeFromParameters("a", atom("a"));
		checkComposeFromParameters("{a,P0}", tuple(atom("a"), string("Val0")), "Val0");
		checkComposeFromParameters("[a,P0,P1]", list(atom("a"), string("Val0"), integer(10)), "Val0", 10);
		checkComposeFromParameters("[a,P0,P1]", list(atom("a"), string("Val0"), floating(1.0)), "Val0", 1.0);
		checkComposeFromParameters("{a,P0,P1}", tuple(atom("a"), string("Val0"), integer(10)), "Val0", 10);
		checkComposeFromParameters("{X,P0,P1}", tuple(string("x"), string("Val0"), integer(10)), "Val0", 10);
		checkComposeFromParameters("{a,[P0,P1]}", tuple(atom("a"), list(string("Val0"), floating(1.0))), "Val0", 1.0);
	}

	
	public void testWithExceptions(){
		checkException(Erlang4jMissingParameterException.class, "{a,P0}", "Expected a parameter called P0 that wasnt available");
		
	}
	private <T extends Erlang4jMissingParameterException> T checkException(Class<T> expected, final String pattern, String message, final Object...parameters) {
		return Erlang4JTestHelper.assertThrows(expected,message, new Runnable() {
			public void run() {
				messageComposer.compose(pattern, parameters);
			}
		});
	}

	private void checkComposeFromParameters(String string, OtpErlangObject expected, Object... parameters) {
		OtpErlangObject object = messageComposer.compose(string, parameters);
		assertEquals(object, expected);
	}

	private void checkComposeFromBinding(String string, OtpErlangObject expected, Object... bindingDefn) {
		OtpErlangObject object = messageComposer.composeFromBinding(string, binding(bindingDefn));
		assertEquals(object, expected);

	}
}
